package com.leyou.item.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.constants.MQConstants;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exceptions.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.vo.PageResult;
import com.leyou.item.dto.*;
import com.leyou.item.entity.Sku;
import com.leyou.item.entity.Spu;
import com.leyou.item.entity.SpuDetail;
import com.leyou.item.mapper.DetailMapper;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author fenglin
 * @date 2019/12/12 16:34
 */
@Service
public class GoodsService {
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private DetailMapper detailMapper;

    public PageResult<SpuDTO> querySpuByPage(String key, Integer page, Integer rows, Boolean saleable) {
        //构建搜索
        Example example = new Example(Spu.class);
        //过滤条件
        Example.Criteria criteria = example.createCriteria();
        //上下架guolv
        if (saleable != null) {
            criteria.andEqualTo("saleable", saleable);
        }
        //关键字过滤
        if (StringUtils.isNotBlank(key)) {
            criteria.andLike("name", "%" + key + "%");
        }
        //排序
        example.setOrderByClause("update_time DESC");
        //分页
        PageHelper.startPage(page, rows);
        //查询
        List<Spu> list = spuMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        //解析结果
        // 6.1.处理分页结果
        PageInfo<Spu> info = new PageInfo<>(list);
        // 6.2.处理DTO
        List<SpuDTO> dtoList = BeanHelper.copyWithCollection(list, SpuDTO.class);
        // 6.3.处理分类和品牌名称
        handleCategoryBrandName(dtoList);
        return new PageResult<>(info.getTotal(), info.getPages(), dtoList);
    }

    @Autowired
    private BrandService brandService;
    @Autowired
    private CategoryService categoryService;

    private void handleCategoryBrandName(List<SpuDTO> dtoList) {
        for (SpuDTO spuDTO : dtoList) {
            //获取分类
            /*List<Long> categoryIds = spuDTO.getCategoryIds();
            List<CategoryDTO> list=categoryService.queryCategoryByIds(categoryIds);
            StrBuilder strBuilder = new StrBuilder();
            for (CategoryDTO categoryDTO : list) {
                String name = categoryDTO.getName();
                strBuilder.append(name).append("/");
            }
            if (strBuilder.length()>1){
                strBuilder.deleteCharAt(strBuilder.length()-1);
            }
            spuDTO.setCategoryName(strBuilder.toString());*/
            List<Long> categoryIds = spuDTO.getCategoryIds();
            String names = categoryService.queryCategoryByIds(categoryIds)
                    .stream()
                    .map(CategoryDTO::getName)
                    .collect(Collectors.joining("/"));
            spuDTO.setCategoryName(names);
            //获取品牌名称
            Long brandId = spuDTO.getBrandId();
            BrandDTO brand = brandService.queryBrandById(brandId);
            spuDTO.setBrandName(brand.getName());
        }


    }

    @Autowired
    private SkuMapper skuMapper;

    @Transactional//事务
    public void saveGoods(SpuDTO spuDTO) {
        Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
        // 默认下架
        spu.setSaleable(false);
        // 1.新增spu数据
        spuMapper.insertSelective(spu);

        //新增SpuDetail数据
        SpuDetail spuDetail = BeanHelper.copyProperties(spuDTO.getSpuDetail(), SpuDetail.class);
        spuDetail.setSpuId(spu.getId());
        detailMapper.insertSelective(spuDetail);
        //新增sku数据
        insertSku(spuDTO.getSkus(), spu.getId());
    }

    //新增sku数据
    private void insertSku(List<SkuDTO> skuDTOList, Long spuId) {
        List<Sku> skuList = new ArrayList<>();
        for (SkuDTO skuDTO : skuDTOList) {
            // 转换DTO
            Sku sku = BeanHelper.copyProperties(skuDTO, Sku.class);
            sku.setSpuId(spuId);
            // 默认是下架
            sku.setEnable(false);
            skuList.add(sku);
        }
        skuMapper.insertList(skuList);
    }


    @Autowired
    private AmqpTemplate amqpTemplate;
    /**
     * 上下架
     *
     * @param id
     * @param saleable
     */
    @Transactional
    public void updateSpuSaleable(Long id, Boolean saleable) {
        // 1.更新spu  update tb_spu set saleable=1 where id = 1
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(saleable);
        int count = spuMapper.updateByPrimaryKeySelective(spu);
        if (count != 1) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
        // 2.更新sku update tb_sku set saleable=1 where spu_id = 1
        // 2.1.要更新的数据
        Sku sku = new Sku();
        sku.setEnable(saleable);
        Example example = new Example(Sku.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("spuId",id);
        count = skuMapper.updateByExampleSelective(sku, example);

        int size = skuMapper.selectCountByExample(example);
        if (count != size) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
        //发送商品上下架的消息
        String routingKey = saleable ? MQConstants.RoutingKey.ITEM_UP_KEY : MQConstants.RoutingKey.ITEM_DOWN_KEY;
        amqpTemplate.convertAndSend(MQConstants.Exchange.ITEM_EXCHANGE_NAME, routingKey, id);
    }

    /**
     * 根据id查询spu
     * @param id
     * @return
     */
    public SpuDTO  querySpuById(Long id) {
        //查询spu
        Spu spu = spuMapper.selectByPrimaryKey(id);
        if (spu == null) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        SpuDTO spuDTO = BeanHelper.copyProperties(spu, SpuDTO.class);
        // 2.查询spuDetail
        spuDTO.setSpuDetail(queryDetailBySpuId(id));
        // 3.查询skus
        spuDTO.setSkus(querySkuBySpuId(id));
        return spuDTO;
    }

    // 2.查询spuDetail
    public SpuDetailDTO queryDetailBySpuId(Long id) {
        SpuDetail spuDetail = detailMapper.selectByPrimaryKey(id);
        if (spuDetail == null) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyProperties(spuDetail, SpuDetailDTO.class);
    }

    // 3.查询skus
    public List<SkuDTO> querySkuBySpuId(Long id) {
        Sku sku = new Sku();
        sku.setSpuId(id);
        List<Sku> list = skuMapper.select(sku);
        if (CollectionUtils.isEmpty(list)) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(list, SkuDTO.class);
    }

    /**
     * 修改商品
     * @param spuDTO
     */
    @Transactional
    public void updateGoods(SpuDTO spuDTO) {
        //修改spu表
        Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
        spu.setSaleable(null);
        int count = spuMapper.updateByPrimaryKeySelective(spu);
        if(count != 1){
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }

        //修改spuDetail
        SpuDetail spuDetail = BeanHelper.copyProperties(spuDTO.getSpuDetail(), SpuDetail.class);
        count = detailMapper.updateByPrimaryKeySelective(spuDetail);
        if(count != 1){
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }

        //删除sku
        Sku sku = new Sku();
        sku.setSpuId(spu.getId());
        int size = skuMapper.selectCount(sku);
        if(size > 0) {
            count = skuMapper.delete(sku);
            if (count != size) {
                throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
            }
        }
        // 4.新增sku
        insertSku(spuDTO.getSkus(), spu.getId());
    }
}
